﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using EPiServer.Data.Dynamic;
using System.Collections.Generic;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.Core.Html;

namespace EPiServer.Research.MobileCenterGadgetLib
{
    /// <summary>
    /// Shows the difference between properties
    /// </summary>
    public class PropertyDiff
    {

        
        /// <summary>
        /// Gets the property changes. Compares to PageReferences versions by comparing properties to its previous one. 
        /// </summary>
        /// <param name="first">The first.</param>
        /// <param name="second">The second.</param>
        /// <returns></returns>
        public static Version GetPropertyChanges(PageVersion first, PageVersion second)
        {
            List<Version> versions = new List<Version>();

            PageData previousVersion = DataFactory.Instance.GetPage(second.ID);

            PageData pageData = DataFactory.Instance.GetPage(first.ID);


            Version version = new Version(first.ID.WorkID, first.SavedBy, first.Saved, first.Status.ToString());


            List<PropertyChange> changes = new List<PropertyChange>();

            for (int i = 0; i < pageData.Property.Count; i++)
            {
                PropertyData prop = pageData.Property[i];
                PropertyData prev = previousVersion.Property[prop.Name];

                EPiServer.DataAbstraction.TabDefinition tab = EPiServer.DataAbstraction.TabDefinition.Load(prop.OwnerTab);

                if (prop.DisplayEditUI == false || null == tab)
                    continue;


                if (!pageData.QueryDistinctAccess(tab.RequiredAccess))
                    continue;

                //if they arent in the edit mode nor is a pagelink then continue

                if (prop.IsNull && prev.IsNull)
                    continue;



                //if they are different then add to list
                //issue, should we striphtml, say we only show a link or an image
                //probably not right
                if (prop.IsNull ||
                    prev.IsNull ||
                    prop.Value.ToString() != prev.Value.ToString())
                {

                    string valold = (prev.Value != null) ? prev.Value.ToString() : String.Empty;
                    string valnew = (prop.Value != null) ? prop.Value.ToString() : String.Empty;
                    changes.Add(new PropertyChange(prop.TranslateDisplayName(), TextIndexer.StripHtml(valold, 100), TextIndexer.StripHtml(valnew, 100)));
                }
            }

            version.Changes = (PropertyChange[])changes.ToArray();

            return version;


        }

    }

    /// <summary>
    /// Help class for Property Changes
    /// </summary>
    public class PropertyChange
    {
        protected string _name, _oldvalue, _newvalue;

        public PropertyChange(string name, string oldvalue, string newvalue)
        {
            _name = name;
            _oldvalue = oldvalue;
            _newvalue = newvalue;
        }

        public string Name
        {
            get
            {
                return _name;
            }
        }
        public string OldValue
        {
            get
            {
                return _oldvalue;
            }
        }
        public string NewValue
        {
            get
            {
                return _newvalue;
            }
        }
    }

    /// <summary>
    /// Help class for different Versions
    /// </summary>
    public class Version
    {
        protected int _version;
        protected string _savedBy;
        protected DateTime _saved;
        protected string _status;

        PropertyChange[] _changes = new PropertyChange[0] { };

        public Version(int version, string savedBy, DateTime saved, string status)
        {
            _version = version;
            _savedBy = savedBy;
            _saved = saved;
            _status = status;
        }

        public int VersionID
        {
            get
            {
                return _version;
            }
        }

        public string SavedBy
        {
            get
            {
                return _savedBy;
            }
        }

        public DateTime Saved
        {
            get
            {
                return _saved;
            }
        }

        public string Status
        {
            get
            {
                return _status;
            }
        }

        public PropertyChange[] Changes
        {
            get
            {
                return _changes;
            }
            set
            {
                _changes = value;
            }
        }

        public string CountChanges
        {
            get
            {
                return _changes.Length.ToString();
            }
        }
    }
}
